<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
    />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Native three.js with Physics</title>
    <link rel="stylesheet" href="/css/examples.css?ver=1.0.0" />
    <script src="/js/examples.js?ver=1.1.1"></script>
    <script src="/lib/three.min.js"></script>
    <script src="/lib/enable3d/enable3d.ammoPhysics.0.22.0.min.js"></script>
    <script src="/lib/OrbitControls.js"></script>
  </head>

  <body>
    <script>
      const { AmmoPhysics, PhysicsLoader } = ENABLE3D

      const MainScene = () => {
        const scene = new THREE.Scene()
        scene.background = new THREE.Color(0xf0f0f0)

        const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000)
        camera.position.set(10, 10, 20)

        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const DPR = window.devicePixelRatio
        renderer.setPixelRatio(Math.min(2, DPR))

        const controls = new THREE.OrbitControls(camera, renderer.domElement)
        controls.target.set(0, 2, 0)
        camera.lookAt(0, 2, 0)

        scene.add(new THREE.HemisphereLight(0xffffbb, 0x000000, 0.5))
        scene.add(new THREE.AmbientLight(0xffffff, 0.5))
        const light = new THREE.DirectionalLight(0xffffff, 0.5)
        light.position.set(50, 200, 100)
        light.position.multiplyScalar(1.3)

        const physics = new AmmoPhysics(scene)
        physics.debug.enable(true)

        // balls
        physics.add.sphere({ z: -1 }, { lambert: { color: 'darkolivegreen' } })
        physics.add.sphere({ z: 0 }, { lambert: { color: 'darkorchid' } })
        physics.add.sphere({ z: -1, y: 2.5 }, { lambert: { color: 'firebrick' } })

        // static ground
        physics.add.ground({ width: 20, height: 20 }, { lambert: { color: 'cadetblue' } })

        // ------------------------
        // add outer cylinder using extrude (https://stackoverflow.com/a/31107090)
        // ------------------------
        const extrudeSettings = {
          depth: 2,
          steps: 1,
          bevelEnabled: false,
          curveSegments: 8
        }

        const arcShape = new THREE.Shape()
        arcShape.absarc(0, 0, 4, 0, Math.PI * 2, 0, false)

        const holePath = new THREE.Path()
        holePath.absarc(0, 0, 3.5, 0, Math.PI * 2, true)
        arcShape.holes.push(holePath)

        const geo = new THREE.ExtrudeBufferGeometry(arcShape, extrudeSettings)
        const mat = new THREE.MeshBasicMaterial({ color: 'khaki' })
        const mesh = new THREE.Mesh(geo, mat)
        geo.translate(0, 0, -1) // somehow this has an offset as well :/
        mesh.rotateX(Math.PI / 2)
        mesh.position.y = 15
        scene.add(mesh)
        physics.add.existing(mesh, { shape: 'hacd' })

        // ------------------------

        const clock = new THREE.Clock()

        const animate = () => {
          physics.update(clock.getDelta() * 1000)
          physics.updateDebugger()
          renderer.render(scene, camera)

          requestAnimationFrame(animate)
        }
        requestAnimationFrame(animate)
      }
      PhysicsLoader('/lib/ammo/moz', () => MainScene())

      console.log(`three.js version "${THREE.REVISION}"`)
    </script>
  </body>
</html>
